package com.sesame.sso.menu.service;

import com.sesame.basic.ProjectConfig;
import com.sesame.sso.cache.SsoCacheServer;
import com.sesame.sso.menu.bean.SsoMenu;
import com.sesame.sso.menu.bean.SysFunction;
import com.sesame.sso.menu.dao.SsoMenuDao;
import com.sesame.sso.role.service.SsoRoleService;
import kim.sesame.framework.entity.GMap;
import kim.sesame.framework.entity.ZTree;
import kim.sesame.framework.utils.GData;
import kim.sesame.framework.utils.StringUtil;
import kim.sesame.framework.utils.UUIDUtil;
import kim.sesame.framework.web.context.UserContext;
import kim.sesame.framework.web.entity.IUser;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * SsoMenuService
 *
 * @author wangjianghai
 * @date 2018-01-26 16:03:52
 * @Description: 菜单表
 */
@CommonsLog
@Service
public class SsoMenuService {

    @SuppressWarnings("all")
    @Resource
    private SsoMenuDao ssoMenuDao;

    @Autowired
    private SsoRoleService ssoRoleService;

    @Autowired
    private SsoCacheServer ssoCacheServer;

    /**
     * 查询list
     *
     * @author wangjianghai
     * @date 2018-01-26 16:03:52
     * @Description: 分页时要注意
     */
    public List<SsoMenu> searchList(SsoMenu bean) {

        List<SsoMenu> list = ssoMenuDao.selectList(bean);

        return list;
    }

    /**
     * 新增
     *
     * @author wangjianghai
     * @date 2018-01-26 16:03:52
     * @Description:
     */
    @Transactional(rollbackFor = Exception.class)
    public int add(SsoMenu bean) {

        if (StringUtil.isEmpty(bean.getIcon())) {
            if (bean.getGrade().toString().equals("1")) {
                bean.setIcon("&#xe614;");
            }
            if (bean.getGrade().toString().equals("2")) {
                bean.setIcon("&#xe641;");
            }
        }
        if (StringUtil.isEmpty(bean.getSequence())) {
            bean.setSequence(1000);
        }
        IUser user = UserContext.getUserContext().getUser();
        bean.initCreateAndId(user.getAccount());

        int res = this.insert(bean);

        SsoMenu sm = null;
        if (bean.getList() != null && bean.getList().size() > 0) {
            SysFunction sf = null;
            for (int i = 0; i < bean.getList().size(); i++) {
                sf = bean.getList().get(i);
                sm = new SsoMenu(bean.getSystemCode(), sf.getKey(), sf.getName(), bean.getCode(), i + 1);
                sm.initCreateAndId(user.getAccount());
                this.insert(sm);
            }
        }

        return res;
    }

    public int insert(SsoMenu bean) {
        bean.setNotdele(GData.BOOLEAN.YES);
        int res = ssoMenuDao.insert(bean);
        // 给超级管理员添加权限
        GMap params = GMap.newMap(); //values  (#{roleCode},#{menuCode},#{systemCode})
        params.putAction("roleCode", ProjectConfig.SpuerAdmin);
        params.putAction("menuCode", bean.getCode());
        params.putAction("systemCode", bean.getSystemCode());

        res = ssoMenuDao.initInsertAdmin(params);

        // 给当前登录的用户添加权限
        String userRole = ssoRoleService.getMaxRole().getCode();
        if (!userRole.equals(ProjectConfig.SpuerAdmin)) {
            params.putAction("roleCode", userRole);
            res = ssoMenuDao.initInsertAdmin(params);
        }
        return res;
    }

    /**
     * 修改
     *
     * @author wangjianghai
     * @date 2018-01-26 16:03:52
     * @Description:
     */
    @Transactional(rollbackFor = Exception.class)
    public int update(SsoMenu bean) {

        int res = this.updateState(bean);

        SsoMenu sm = null;
        // 1先删除没有的数据
        List<String> list_id = new ArrayList<>();
        List<SysFunction> list = null;
        if (bean.getList() != null) {
            list = bean.getList().stream().filter(s -> StringUtil.isNotEmpty(s.getKey()) && StringUtil.isNotEmpty(s.getName()))
                    .collect(Collectors.toList());
        }

        if (list != null && list.size() > 0) {

            for (SysFunction sf : list) {
                if (sf.getId() != null) {
                    list_id.add(sf.getId());
                }
            }
            if (list_id.size() > 0) {
                String str = list_id.stream().map(s ->
                        "'" + s + "'"
                ).collect(Collectors.toList()).toString();
                str = str.substring(1, str.length() - 1);
                GMap params = GMap.newMap();
                params.putAction("parentCode", bean.getCode());
                params.putAction("systemCode", bean.getSystemCode());
                params.putAction("str", str);

                ssoMenuDao.initDeleteMenu(params);
                ssoMenuDao.updateDelete(params);
            }
        }

        // 2添加或修改数据
        if (list != null && list.size() > 0) {
            for (SysFunction sf : list) {
                if (sf.getId() != null) {
                    // update
                    sm = new SsoMenu(sf.getName(), sf.getKey(), bean.getCode(), bean.getSystemCode());
                    sm.setId(sf.getId());
                    ssoMenuDao.update(sm);
                } else {
                    // add
                    sm = new SsoMenu(sf.getName(), sf.getKey(), bean.getCode(), bean.getSystemCode());
                    sm.setId(UUIDUtil.getShortUUID());
                    this.insert(sm);
                }

            }
        }


        return res;
    }

    /**
     * 菜单开启,禁止方法
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateState(SsoMenu bean) {

        // 1 修改
        int res = ssoMenuDao.update(bean);

        if (StringUtil.isNotEmpty(bean.getIsEnable())) {
            // 2 再查询这个菜单下的子菜单
            bean = this.search(new SsoMenu(bean.getId()));

            // 3 判断有没有子菜单 ,如果有 就递归继续修改
            String isEnable = bean.getIsEnable();
            if (bean.getList() != null) {
                bean.getList().forEach(s -> {
                    SsoMenu ss = new SsoMenu();
                    ss.setId(s.getId());
                    ss.setIsEnable(isEnable);

                    this.updateState(ss);
                });
            }

        }
        return res;
    }

    /**
     * 删除
     *
     * @author wangjianghai
     * @date 2018-01-26 16:03:52
     * @Description:
     */
    @Transactional(rollbackFor = Exception.class)
    public int delete(String ids) {

        List<String> list_id = Stream.of(ids.split(",")).map(String::trim).distinct().filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        list_id.stream().forEach(this::deleteById);

        return list_id.size();
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) {
        //物理删除

        SsoMenu bean = this.search(new SsoMenu(id));

        ssoMenuDao.delete(id);

        // 2 删除对应的权限
        ssoMenuDao.deleteRoleMenu(bean);

        // 3 递归删除
        if (bean.getList() != null) {
            bean.getList().forEach(s -> {
                this.deleteById(s.getId());
            });
        }
        //逻辑删除
        //    SsoMenu bean = new SsoMenu();
        //    	bean.setId(id);
        //    	bean.setActive(GData.BOOLEAN.NO);
        //    	bean.setUpdateTime(new Date());
        //    	update(bean);
    }

    /**
     * 查询--返回bean
     *
     * @author wangjianghai
     * @date 2018-01-26 16:03:52
     * @Description:
     */
    public SsoMenu search(SsoMenu bean) {

        SsoMenu resBean = ssoMenuDao.search(bean);

        // 查询二级菜单下的所有功能按钮
        if (resBean.getGrade().equals(2) || resBean.getGrade().equals(1)) {
            List<SysFunction> list = ssoMenuDao.searchChildMenu(resBean);
            resBean.setList(list);
        }

        return resBean;
    }

    /**
     * 根据用户编号查询list的菜单
     *
     * @param account    用户编号
     * @param systemCode 系统编号
     * @return
     */
    public List<SsoMenu> getMenuByUserCode(String account, String systemCode) {

        return ssoCacheServer.queryMenuByUserCode(account, systemCode);
    }


    /**
     * 获取菜单树结构数据
     *
     * @param systemCode 系统编号
     * @param roleCode   角色编号
     * @return
     */
    public List<ZTree> searchRoleMenu(String systemCode, String roleCode) {
        GMap params = GMap.newMap();
        params.putAction("systemCode", systemCode);
        params.putAction("roleCode", roleCode);
        params.putAction("userRoleCodes", ssoRoleService.getUserRoleCodes());

        List<ZTree> list = ssoMenuDao.searchRoleMenu(params);
        return list;
    }

    /**
     * 保存节点数据
     *
     * @param systemCode 系统编号
     * @param roleCode   角色编号
     * @param menuCodes  菜单节点集合,  逗号分隔
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveMenuTreeData(String systemCode, String roleCode, String menuCodes) {
        GMap params = GMap.newMap();
        params.putAction("systemCode", systemCode);
        params.putAction("roleCode", roleCode);

        // 1 先清除原来的数据
        ssoMenuDao.cleanRoleMenu(params);

        //2 保存数据
        List<String> codes = Arrays.asList(menuCodes.split(","));
        if (codes != null && codes.size() > 0) {
            params.putAction("codes", codes);

            ssoMenuDao.saveRoleMenu(params);
        }

    }

    public List<GMap> queryUserMenu(String account, String systemCode, String basePath) {
        List<GMap> list_GMap = new ArrayList<GMap>();
        List<GMap> children = null;

        List<SsoMenu> list = getMenuByUserCode(account, systemCode);

        GMap gMap = null;
        for (SsoMenu sm1 : list) {
            if (sm1.getGrade() == 1) {
                gMap = GMap.newMap();
                gMap.putAction("title", sm1.getName());
                gMap.putAction("icon", sm1.getIcon() == null ? "&#xe620;" : sm1.getIcon());
                gMap.putAction("spread", false);

                children = new ArrayList<>();
                for (SsoMenu sm2 : list) {
                    if (sm2.getGrade() == 2 && sm2.getParentCode().equals(sm1.getCode())) {

                        GMap params = GMap.newMap();
                        params.putAction("title", sm2.getName());
                        params.putAction("icon", sm2.getIcon() == null ? "&#xe609;" : sm2.getIcon());
                        params.putAction("href", basePath + "/" + sm2.getUrl());

                        children.add(params);
                    }
                }
                gMap.putAction("children", children);

                list_GMap.add(gMap);
            }
        }

        return list_GMap;
    }
}
